<template>
  <n-timeline class="go-chart-configurations-timeline">
    <n-timeline-item v-show="isCharts && dimensionsAndSource" type="info" :title="TimelineTitleEnum.MAPPING">
      <n-table striped>
        <thead>
        <tr>
          <th v-for="item in tableTitle" :key="item">{{ item }}</th>
        </tr>
        </thead>
        <tbody>
        <tr v-for="(item, index) in dimensionsAndSource" :key="index">
          <td>{{ item.field }}</td>
          <td>{{ item.mapping }}</td>
          <td>
            <n-space v-if="item.result === 0">
              <n-badge dot type="success"></n-badge>
              <n-text>无</n-text>
            </n-space>
            <n-space v-else>
              <n-badge dot :type="item.result === 1 ? 'success' : 'error'"></n-badge>
              <n-text>匹配{{ item.result === 1 ? '成功' : '失败' }}</n-text>
            </n-space>
          </td>
        </tr>
        </tbody>
      </n-table>
    </n-timeline-item>
    <n-timeline-item v-show="filterShow" color="#97846c" :title="TimelineTitleEnum.FILTER">
      <n-space :size="18" vertical>
        <n-text depth="3">过滤器默认处理接口返回值的「data」字段</n-text>
        <chart-data-monaco-editor></chart-data-monaco-editor>
      </n-space>
    </n-timeline-item>
    <n-timeline-item type="success" :title="TimelineTitleEnum.CONTENT">
      <n-space vertical>
        <n-space class="source-btn-box">
          <n-upload
              v-model:file-list="uploadFileListRef"
              :show-file-list="false"
              :customRequest="customRequest"
              @before-upload="beforeUpload"
          >
            <n-space>
              <n-button v-if="!ajax" class="sourceBtn-item" :disabled="noData" size="small">
                <template #icon>
                  <n-icon>
                    <document-add-icon/>
                  </n-icon>
                </template>
                导入（json / txt）
              </n-button>
            </n-space>
          </n-upload>
          <div>
            <n-button-group size="small">
              <n-button class="sourceBtn-item" :disabled="noData" @click="download">
                <template #icon>
                  <n-icon>
                    <document-download-icon/>
                  </n-icon>
                </template>
                下载
              </n-button>
              <n-button class="sourceBtn-item" @click="edit">
                编辑
              </n-button>
            </n-button-group>
          </div>
        </n-space>
        <n-card size="small">
          <n-code :code="toString(source)" language="json"></n-code>
        </n-card>
      </n-space>
    </n-timeline-item>
  </n-timeline>
  <n-modal
      v-model:show="showEditDataModal"
      preset="dialog" :style="{ width: '800px' }"
      title="编辑菜单项" :draggable="true"
      positive-text="保存"
      negative-text="取消"
      @positive-click="submitCallback"
      @negative-click="cancelCallback"
  >
    <div class="m-events">
      <div class="m-event-item">
        <n-input value="名称" disabled type="text" placeholder="名称"/>
        <n-input value="值" disabled type="text" placeholder="值"/>
        <n-input value="触发事件" disabled type="text" placeholder="触发事件"/>
      </div>
      <div v-for="(item,index) in source" :key="item" class="m-event-item">
        <n-input v-model:value="item.label" type="text" placeholder="名称"/>
        <n-input v-model:value="item.value" type="text" placeholder="值"/>
        <n-select v-model:value="item.event" label-field="name"	value-field="value" :options="events"/>
        <n-icon size="22" class="event-item-option" @click="optionBtn(item,index,'add')" v-if="index===source.length-1">
          <AddIcon/>
        </n-icon>
        <n-icon size="22" class="event-item-option" @click="optionBtn(item,index,'delete')" v-if="source.length>0">
          <RemoveIcon/>
        </n-icon>
      </div>
    </div>
  </n-modal>
</template>

<script setup lang="ts">
import {ref, computed, watch, onMounted} from 'vue'
import {ChartFrameEnum} from '@/packages/index.d'
import {RequestDataTypeEnum} from '@/enums/httpEnum'
import {icon} from '@/plugins'
import {DataResultEnum, TimelineTitleEnum} from '../../index.d'
import {ChartDataMonacoEditor} from '../ChartDataMonacoEditor'
import {useFile} from '../../hooks/useFile.hooks'
import {useTargetData} from '../../../hooks/useTargetData.hook'
import {toString, isArray} from '@/utils'
import { AppParams } from '@/utils/appParams'

const {targetData} = useTargetData()
const props = defineProps({
  show: {
    type: Boolean,
    required: false
  },
  ajax: {
    type: Boolean,
    required: true
  }
})

const events =AppParams.INTERACTION_EVENT
// const events = ref<{ label: string, value: string }[]>([])

const showEditDataModal = ref(false)
// 表格标题
const tableTitle = ['字段', '映射', '状态']

const {HelpOutlineIcon, AddIcon, RemoveIcon, ChevronUpIcon, ChevronDownIcon} = icon.ionicons5
const {DocumentAddIcon, DocumentDownloadIcon} = icon.carbon

const source = ref()
const dimensions = ref()
const dimensionsAndSource = ref()
const noData = ref(false)

const {uploadFileListRef, customRequest, beforeUpload, download} = useFile(targetData)

const HandleEvent = () => {
  for (let ev in AppParams.INTERACTION_EVENT) {
    events.value.push({label: ev, value: ev})
  }
}

const optionBtn = (item: object, index: number, option: string) => {
  switch (option) {
    case 'add':
      source.value.push({label: '名称', value: '值', event: null})
      break;
    case 'delete':
      source.value.splice(index, 1)
      break;
    case 'up':
      source.value.splice(index - 1, 1)
      source.value.splice(index, 1, source.value[index])
      break;
    case 'down':
      source.value.splice(index, 1)
      source.value.splice(index + 2, 0, source.value[index])
      break;
  }
}

// 是否展示过滤器
const filterShow = computed(() => {
  return targetData.value.request.requestDataType !== RequestDataTypeEnum.STATIC
})


const cancelCallback = () => {
}

const submitCallback = () => {
  targetData.value.option.dataset = source.value
}

// 是支持 dataset 的图表类型
const isCharts = computed(() => {
  return targetData.value.chartConfig.chartFrame === ChartFrameEnum.ECHARTS
})

// 处理映射列表状态结果
const matchingHandle = (mapping: string) => {
  let res = DataResultEnum.SUCCESS
  for (let i = 0; i < source.value.length; i++) {
    if (source.value[i][mapping] === undefined) {
      res = DataResultEnum.FAILURE
      return res
    }
  }
  return DataResultEnum.SUCCESS
}

// 处理映射列表
const dimensionsAndSourceHandle = () => {
  try {
    // 去除首项数据轴标识
    return dimensions.value.map((dimensionsItem: string, index: number) => {
      return index === 0
          ? {
            // 字段
            field: '通用标识',
            // 映射
            mapping: dimensionsItem,
            // 结果
            result: DataResultEnum.NULL
          }
          : {
            field: `数据项-${index}`,
            mapping: dimensionsItem,
            result: matchingHandle(dimensionsItem)
          }
    })
  } catch (error) {
    return []
  }
}
onMounted(() => {
  // HandleEvent()
})
watch(
    () => targetData.value?.option?.dataset,
    (
        newData?: {
          source: any
          dimensions: any
        } | null
    ) => {
      noData.value = false
      if (newData && targetData?.value?.chartConfig?.chartFrame === ChartFrameEnum.ECHARTS) {
        // 只有 DataSet 数据才有对应的格式
        source.value = newData
        if (isCharts.value) {
          dimensions.value = newData.dimensions
          dimensionsAndSource.value = dimensionsAndSourceHandle()
        }
      } else if (newData !== undefined && newData !== null) {
        dimensionsAndSource.value = null
        source.value = newData
      } else {
        noData.value = true
        source.value = '此组件无数据源'
      }
      if (isArray(newData)) {
        dimensionsAndSource.value = null
      }
    },
    {
      immediate: true
    }
)


const edit = () => {
  showEditDataModal.value = true
}

// const _source = computed(() => {
//   return toString(source)
// })
</script>

<style lang="scss" scoped>
@include go('chart-configurations-timeline') {
  @include deep() {
    pre {
      white-space: pre-wrap;
      word-wrap: break-word;
    }
  }
  .source-btn-box {
    margin-top: 10px !important;
  }
}

.m-events {
  .m-event-item {
    display: flex;
    margin-bottom: 6px;

    > div {
      margin-right: 6px;
    }

    .event-item-option {
      cursor: pointer;
    }
  }
}
</style>
